package com.cw.lang.common.mapper.common.version;

import org.apache.ibatis.annotations.Param;

import com.cw.lang.common.enums.EnumMybatisError;
import com.cw.lang.common.exception.DBException;

import tk.mybatis.mapper.annotation.RegisterMapper;
import tk.mybatis.mapper.common.Mapper;

/**
 * 乐观锁实现，仅针对于model中有字段带有{@link tk.mybatis.mapper.annotation.Version}注解，即有乐观锁的表
 *
 * @author chenw
 * @version $$Id: VersionMapper.java, v 0.1 2019/2/22 9:51 AM chenw Exp $$
 */
@RegisterMapper
public interface VersionMapper<T> extends Mapper<T> {

    /**
     * 根据实体属性作为条件进行删除，查询条件使用等号，乐观锁不过会抛异常
     *
     * @param record 记录
     * @return 操作记录数
     */
    default int deleteWithVersion(T record) {
        int result = delete(record);
        if (result == 0) {
            throw new DBException(EnumMybatisError.DELETE_ERROR.getCode(),
                EnumMybatisError.DELETE_ERROR.getDescription());
        }
        return result;
    }

    /**
     * 根据主键字段进行删除，方法参数必须包含完整的主键属性，乐观锁不过会抛异常
     *
     * @param key 主键
     * @return 操作记录数
     */
    default int deleteByPrimaryKeyWithVersion(Object key) {
        int result = deleteByPrimaryKey(key);
        if (result == 0) {
            throw new DBException(EnumMybatisError.DELETE_ERROR.getCode(),
                EnumMybatisError.DELETE_ERROR.getDescription());
        }
        return result;
    }

    /**
     * 根据主键更新实体全部字段，null值会被更新，乐观锁不过会抛异常
     *
     * @param record 记录
     * @return 操作记录数
     */
    default int updateByPrimaryKeyWithVersion(T record) {
        int result = updateByPrimaryKey(record);
        if (result == 0) {
            throw new DBException(EnumMybatisError.UPDATE_ERROR.getCode(),
                EnumMybatisError.UPDATE_ERROR.getDescription());
        }
        return result;
    }

    /**
     * 根据主键更新属性不为null的值，乐观锁不过会抛异常
     *
     * @param record 记录
     * @return 操作记录数
     */
    default int updateByPrimaryKeySelectiveWithVersion(T record) {
        int result = updateByPrimaryKeySelective(record);
        if (result == 0) {
            throw new DBException(EnumMybatisError.UPDATE_ERROR.getCode(),
                EnumMybatisError.UPDATE_ERROR.getDescription());
        }
        return result;
    }

    /**
     * 根据Example条件更新实体`record`包含的全部属性，null值会被更新，乐观锁不过会抛异常
     *
     * @param record 记录
     * @param example 条件
     * @return 操作记录数
     */
    default int updateByExampleWithVersion(@Param("record") T record, @Param("example") Object example) {
        int result = updateByExample(record, example);
        if (result == 0) {
            throw new DBException(EnumMybatisError.UPDATE_ERROR.getCode(),
                EnumMybatisError.UPDATE_ERROR.getDescription());
        }
        return result;
    }

    /**
     * 根据Example条件更新实体`record`包含的不是null的属性值，乐观锁不过会抛异常
     *
     * @param record 记录
     * @param example 条件
     * @return 操作记录数
     */
    default int updateByExampleSelectiveWithVersion(@Param("record") T record, @Param("example") Object example) {
        int result = updateByExampleSelective(record, example);
        if (result == 0) {
            throw new DBException(EnumMybatisError.UPDATE_ERROR.getCode(),
                EnumMybatisError.UPDATE_ERROR.getDescription());
        }
        return result;
    }
}
